﻿#include <windows.h>
#include <iostream>
#include <thread>

void StartTextInput(HWND hwnd, POINT position)
{
    //创建输入上下文
    HIMC hIMC = ImmCreateContext();
    //设置输入上下文
    ImmAssociateContext(hwnd, hIMC);
    //设置输入位置
    COMPOSITIONFORM cf;
    cf.dwStyle = CFS_POINT;
    cf.ptCurrentPos = position;
    ImmSetCompositionWindow(hIMC, &cf);
    //设置输入状态
    ImmSetOpenStatus(hIMC, TRUE);
}

void EndTextInput()
{
    //获取输入上下文
    HIMC hIMC = ImmGetContext(GetFocus());
    //关闭输入状态
    ImmSetOpenStatus(hIMC, FALSE);
    //释放输入上下文
    ImmReleaseContext(GetFocus(), hIMC);
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
    case WM_CLOSE:
        DestroyWindow(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;

    //键盘按下A 则开始文本输入
    //键盘按下S 则结束文本输入

    case WM_KEYDOWN:
        if (wParam == 'A')
        {
            //开始文本输入
            std::cout << "StartTextInput" << std::endl;
            StartTextInput(hwnd, {0, 0});
        }
        else if (wParam == 'S')
        {
            std::cout << "EndTextInput" << std::endl;
            //结束文本输入
            EndTextInput();
        }
        break;

    //输入法输入,在输入法选好字符后会发送这个消息
    case WM_IME_COMPOSITION:
    {
        //获取输入法上下文
        HIMC hIMC = ImmGetContext(hwnd);
        //获取输入法信息
        DWORD dwSize = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0);
        if (dwSize > 0)
        {
            //获取输入法结果
            char *pResult = new char[dwSize];
            ImmGetCompositionString(hIMC, GCS_RESULTSTR, pResult, dwSize);
            std::cout << "Input: " << pResult << std::endl;
            delete[] pResult;
        }
        ImmReleaseContext(hwnd, hIMC);
    }



    default:
        return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}


int main()
{
    //使用windows api 创建一个窗口

    // //1. 注册窗口类
    // WNDCLASS wc = {0};
    // wc.lpfnWndProc = WndProc;
    // wc.hInstance = GetModuleHandle(NULL);
    // wc.lpszClassName = "InputTest";
    // RegisterClass(&wc);

    // //2. 创建窗口
    // HWND hwnd = CreateWindow(wc.lpszClassName, "InputTest", WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, NULL, NULL, wc.hInstance, NULL);
    
    // //3. 显示窗口
    // ShowWindow(hwnd, SW_SHOW);

    // //4. 消息循环
    // MSG msg = {0};

    // while (GetMessage(&msg, NULL, 0, 0))
    // {
    //     TranslateMessage(&msg);
    //     DispatchMessage(&msg);
    // }


    //使用子线程处理消息
    std::thread([]() {
        //1. 注册窗口类
        WNDCLASS wc = {0};
        wc.lpfnWndProc = WndProc;
        wc.hInstance = GetModuleHandle(NULL);
        wc.lpszClassName = "InputTest";
        RegisterClass(&wc);

        //2. 创建窗口
        HWND hwnd = CreateWindow(wc.lpszClassName, "InputTest", WS_OVERLAPPEDWINDOW, 0, 0, 800, 600, NULL, NULL, wc.hInstance, NULL);
        
        //3. 显示窗口
        ShowWindow(hwnd, SW_SHOW);

        //4. 消息循环
        MSG msg = {0};

        while (GetMessage(&msg, NULL, 0, 0))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }).detach();

    //主线程等待
    while (true)
    {
        Sleep(1);
    }

    return 0;
}